package com.firewolf.shiro.helloworld;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.junit.Test;

/**
 * @Description: 1、首先通过new
 *               IniSecurityManagerFactory并指定一个ini配置文件来创建一个SecurityManager工厂；
 *               2、接着获取SecurityManager并绑定到SecurityUtils，这是一个全局设置，设置一次即可；
 *               3、通过SecurityUtils得到Subject，其会自动绑定到当前线程；如果在web环境在请求结束时需要解除绑定；然后获取身份验证的Token，如用户名/密码；
 *               4、调用subject.login方法进行登录，其会自动委托给SecurityManager.login方法进行登录；
 *               5、如果身份验证失败请捕获AuthenticationException或其子类，常见的如：
 *               DisabledAccountException（禁用的帐号）、LockedAccountException（锁定的帐号）、UnknownAccountException（错误的帐号）、ExcessiveAttemptsException（登录失败次数过多）、IncorrectCredentialsException
 *               （错误的凭证）、ExpiredCredentialsException（过期的凭证）等，具体请查看其继承关系；对于页面的错误消息展示，最好使用如“用户名/密码错误”而不是“用户名错误”/“密码错误”，防止一些恶意用户非法扫描帐号库；
 *               6、最后可以调用subject.logout退出，其会自动委托给SecurityManager.logout方法退出。
 * @Author: 刘兴
 * @Date : 2016年7月20日
 * @package : com.firewolf.shiro
 * @Java_Version : 1.7
 * @Version : 2016年7月20日上午11:17:24
 */
public class LoginLogout {

	@Test
	public void testHelloworld() {
		// 1、获取SecurityManager工厂，此处使用Ini配置文件初始化SecurityManager
		Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:users.ini");
		// 2、得到SecurityManager实例 并绑定给SecurityUtils
		// 有一个java.lang.SecurityManager的类，所以这里得指明包名
		org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
		SecurityUtils.setSecurityManager(securityManager);

		// 3、得到Subject及创建用户名/密码身份验证Token（即用户身份/凭证）
		Subject subject = SecurityUtils.getSubject();
		UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123");
		try {
			// 4、登录，即身份验证
			subject.login(token);
		} catch (UnknownAccountException e) {
			System.out.println("账号不存在!");
			e.printStackTrace();
		} catch (IncorrectCredentialsException e) {
			System.out.println("密码不正确!");
			e.printStackTrace();
		} catch (AuthenticationException e) {
			System.out.println("身份认证失败!");
			e.printStackTrace();
		}
		System.out.println(subject.isAuthenticated());
		// 6、退出
		subject.logout();
	}

}
